// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ValueExpiry.cs" company="XamlNinja">
//   2011 Richard Griffin and Ollie Riches
// </copyright>
// <summary>
// </summary>
// <credits>
// Pete Blois http://blois.us/blog/2009/04/datatrigger-bindings-on-non.html
// </credits>
// --------------------------------------------------------------------------------------------------------------------
namespace WP7Contrib.View.Controls.BindingListener
{
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Data;

 
    public class BindingListener
    {

        private static List<DependencyPropertyListener> freeListeners = new List<DependencyPropertyListener>();

        public delegate void ChangedHandler(object sender, BindingChangedEventArgs e);

        private DependencyPropertyListener listener;
        private ChangedHandler changedHandler;
        private Binding binding;
        private FrameworkElement target;
        private object value;

        public BindingListener(ChangedHandler changedHandler)
        {
            this.changedHandler = changedHandler;
        }

        public Binding Binding
        {
            get { return this.binding; }
            set
            {
                this.binding = value;
                this.Attach();
            }
        }

        public FrameworkElement Element
        {
            get { return this.target; }
            set
            {
                this.target = value;
                this.Attach();
            }
        }

        public object Value
        {
            get { return this.value; }
        }


        private void Attach()
        {
            this.Detach();

            if (this.target != null && this.binding != null)
            {
                this.listener = this.GetListener();
                this.listener.Attach(target, binding);
            }
        }

        private void Detach()
        {
            if (this.listener != null)
                this.ReturnListener();
        }

        private DependencyPropertyListener GetListener()
        {
            DependencyPropertyListener listener;

            if (BindingListener.freeListeners.Count != 0)
            {
                listener = BindingListener.freeListeners[BindingListener.freeListeners.Count - 1];
                BindingListener.freeListeners.RemoveAt(BindingListener.freeListeners.Count - 1);

                return listener;
            }
            else
                listener = new DependencyPropertyListener();

            listener.Changed += this.HandleValueChanged;

            return listener;
        }

        private void ReturnListener()
        {
            this.listener.Changed -= this.HandleValueChanged;

            BindingListener.freeListeners.Add(this.listener);

            this.listener = null;
        }

        private void HandleValueChanged(object sender, BindingChangedEventArgs e)
        {
            this.value = e.EventArgs.NewValue;

            this.changedHandler(this, e);

        }
    }
}